package com.rxt.thermopro.widget

import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import com.rxt.thermopro.R

class RulerView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    var MIN_POSITION = 20 //起始位置
    var MAX_POSITION = 1700 //结束位置
    private var mMove: OnMoveActionListener? = null
    private var mLinePaint: Paint //刻度线画笔
    private var mTextPaint: Paint //指示数字画笔
    private var mRulerPaint: Paint  //指示线画笔
    private var imagePaint: Paint
    private var position = -1F
    private var positionLow = -1F
    private var max = 300 //FM频道最大值108*10
    private var min = 0 //FM频道最小值87*10
    private var scaleNum = 50
    private var scaleWidth = 1f
    private var highRect: Rect? = null
    private var lowRect: Rect? = null
    private var tempUnit = "°C"

    /**
     * 定义监听接口
     */
    interface OnMoveActionListener {
        fun onMove(x: Double)
    }

    /**
     * 为每个接口设置监听器
     */
    fun setOnMoveActionListener(move: OnMoveActionListener) {
        mMove = move
    }

    init {
        mLinePaint = Paint()
        mLinePaint.color = resources.getColor(android.R.color.black)
        //抗锯齿
        mLinePaint.isAntiAlias = true
        mLinePaint.style = Paint.Style.STROKE
        mLinePaint.strokeWidth = 1f

        mTextPaint = Paint()
        mTextPaint.color = resources.getColor(android.R.color.black)
        mTextPaint.isAntiAlias = true
        mTextPaint.style = Paint.Style.FILL
        mTextPaint.strokeWidth = 2f
        mTextPaint.textSize = 24f

        mRulerPaint = Paint()
        mRulerPaint.isAntiAlias = true
        mRulerPaint.style = Paint.Style.FILL_AND_STROKE
        mRulerPaint.color = resources.getColor(android.R.color.holo_red_light)
        mRulerPaint.strokeWidth = 3f

        imagePaint = Paint()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        setMeasuredDimension(setMeasureWidth(widthMeasureSpec), setMeasureHeight(heightMeasureSpec))
    }


    private fun setMeasureHeight(spec: Int): Int {
        val mode = MeasureSpec.getMode(spec);
        var size = MeasureSpec.getSize(spec);
        val result = Integer.MAX_VALUE;
        when (mode) {
            MeasureSpec.AT_MOST -> {
                size = result.coerceAtMost(size);
            }
            MeasureSpec.EXACTLY -> {

            }
            else -> {
                size = result
            }
        }
        return size;
    }

    private fun setMeasureWidth(spec: Int): Int {
        val mode = MeasureSpec.getMode(spec);
        var size = MeasureSpec.getSize(spec);
        val result = Integer.MAX_VALUE;
        when (mode) {
            MeasureSpec.AT_MOST -> {
                size = result.coerceAtMost(size)
            }

            MeasureSpec.EXACTLY -> {

            }
            else -> {
                size = result
            }
        }
        return size;
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        canvas?.save()
        val width = width
        val height = height
        scaleWidth = (height - 120).toFloat() / (max - min).toFloat()
//        val a = (height - 120) % (max-min)
        val a = 0
//        int xWidth=
        //        int xWidth=
        MIN_POSITION = 60
        MAX_POSITION = height - 60 - a

        //绘制单位标注
        val rect = Rect()
        val txtWidth = mTextPaint.measureText(tempUnit)
        mTextPaint.getTextBounds(tempUnit, 0, tempUnit.length, rect)
        canvas?.drawText(
            tempUnit,
            60f + txtWidth / 2,
            10f + rect.width(),
            mTextPaint
        )

        Log.d("TAG", "width:$width  height:$height  scaleWidth:$scaleWidth  a=$a")
        canvas!!.translate(0f, (height - a).toFloat())
        //绘制刻度线
        for (i in min..max) {
            if ((i - min) % scaleNum == 0) {
                canvas.drawLine(60f, -60f, 140f, -60f, mLinePaint)
                val text = i.toString() + ""
                val rect = Rect()
                val txtWidth = mTextPaint.measureText(text)
                mTextPaint.getTextBounds(text, 0, text.length, rect)
                canvas.drawText(
                    text,
                    60 - 25 - txtWidth / 2,
                    (-60 + rect.height() / 2).toFloat(),
                    mTextPaint
                )
            } else if ((i - min) % (scaleNum / 10) == 0) {
                canvas.drawLine(60f, -60f, 110f, -60f, mLinePaint)
            }
            canvas.translate(0f, (-scaleWidth).toFloat())
        }
        canvas.restore()

        if (position != -1F && positionLow != -1F) {
            //绘制指示线(High)
            canvas.drawLine(110f, position, (width - 150).toFloat(), position, mRulerPaint)
            val mBitmap = BitmapFactory.decodeResource(resources, R.drawable.progress_bar_high)
            canvas.drawBitmap(
                mBitmap,
                (width - 150 - mBitmap.width / 2).toFloat(),
                position - mBitmap.height / 2,
                imagePaint
            )
            highRect = Rect(
                (width - 150 - mBitmap.width / 2),
                (position - mBitmap.height / 2).toInt(), (width - 150 + mBitmap.width / 2),
                (position + mBitmap.height / 2).toInt()
            )

//        highRect?.let {
//            canvas.drawRect(it, mTextPaint)
//        }

            val text = "High Alarm " + getFmChannel(position).toInt().toString()
            val rect = Rect()
            val txtWidth = mTextPaint.measureText(text)
            mTextPaint.getTextBounds(text, 0, text.length, rect)
            canvas.drawText(
                text,
                (width - 150) / 2 + txtWidth / 2 - 10,
                position - rect.height(),
                mTextPaint
            )

            //绘制指示线(Low)
            canvas.drawLine(110f, positionLow, (width - 150).toFloat(), positionLow, mRulerPaint)
            val mBitmap1 = BitmapFactory.decodeResource(resources, R.drawable.progress_bar_low)
            canvas.drawBitmap(
                mBitmap1,
                (width - 150 - mBitmap1.width / 2).toFloat(),
                positionLow - mBitmap1.height / 2,
                imagePaint
            )
            lowRect = Rect(
                (width - 150 - mBitmap1.width / 2),
                (positionLow - mBitmap1.height / 2).toInt(), (width - 150 + mBitmap1.width / 2),
                (positionLow + mBitmap1.height / 2).toInt()
            )
//        lowRect?.let {
//            canvas.drawRect(it, mTextPaint)
//        }

            val textLow = "Low Alarm " + getFmChannel(positionLow).toInt().toString()
            val rectLow = Rect()
            val txtWidthLow = mTextPaint.measureText(text)
            mTextPaint.getTextBounds(text, 0, text.length, rectLow)
            canvas.drawText(
                textLow,
                (width - 150) / 2 + txtWidthLow / 2 - 10,
                positionLow - rectLow.height(),
                mTextPaint
            )
        }

        mTextPaint.textSize = 24f
    }

    override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
        return super.dispatchTouchEvent(event)
    }

    private var touchHigh = false
    private var touchLow = false
    private var lastX = 0
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {
                touchHigh = highRect?.contains(event.x.toInt(), event.y.toInt()) ?: false
                touchLow = lowRect?.contains(event.x.toInt(), event.y.toInt()) ?: false
                lastX = event.x.toInt()
            }
            MotionEvent.ACTION_MOVE -> {
                val x = event.y
                if (touchLow && touchHigh) {
                    if (x - lastX > 0) {
                        touchHigh = true
                        touchLow = false
                    } else {
                        touchHigh = false
                        touchLow = true
                    }
                }
                when {
                    x < MIN_POSITION -> {
                        if (touchHigh) {
                            setPosition(MIN_POSITION)
                        }
                        if (touchLow) {
                            setLowPosition(MIN_POSITION)
                        }
                    }
                    x > MAX_POSITION -> {
                        if (touchHigh) {
                            setPosition(MAX_POSITION)
                        }
                        if (touchLow) {
                            setLowPosition(MAX_POSITION)
                        }
                    }
                    else -> {
                        if (touchHigh) {
                            setPosition(x.toInt())
                            if (x.toInt() >= positionLow) {
                                setLowPosition(x.toInt())
                            }
                        }
                        if (touchLow) {
                            setLowPosition(x.toInt())
                            if (x.toInt() <= position) {
                                setPosition(x.toInt())
                            }
                        }
                    }
                }
                //移动指示条
                if (mMove != null) {
                    mMove?.onMove(String.format("%.1f", getFmChannel()).toDouble())
                }
                Log.d("TAG", "position:$position")
                Log.d("TAG", "channel:" + getFmChannel())
                //只停在0.1(刻度线上)的位置
                setFmChanel(String.format("%.1f", getFmChannel()).toDouble())
                Log.d("停下来后", "channel:" + String.format("%.1f", getFmChannel()).toDouble())
            }
            MotionEvent.ACTION_CANCEL -> {
                setFmChanel(String.format("%.1f", getFmChannel()).toDouble())
                Log.d("停下来后", "channel:" + String.format("%.1f", getFmChannel()).toDouble())
            }
            else -> {
            }
        }
        return true
    }

    fun setFmChanel(fmChanel: Double) {
        val temp = ((max - fmChanel) * scaleWidth).toInt() + 60
        setPosition(temp)
    }

    fun setLowFmChanel(fmChanel: Double) {
        val temp = ((max - fmChanel) * scaleWidth).toInt() + 60
        setLowPosition(temp)
    }

    fun getFmChannel(): Double {
        val r = max - (position - 60.0) / scaleWidth
        return when {
            r < min -> {
                min.toDouble()
            }
            r > max -> {
                max.toDouble()
            }
            else -> {
                r
            }
        }
    }

    fun getFmChannel(currentPosition: Float): Double {
        val r = max - (currentPosition - 60.0) / scaleWidth
        return when {
            r < min -> {
                min.toDouble()
            }
            r > max -> {
                max.toDouble()
            }
            else -> {
                r
            }
        }
    }

    fun setPosition(i: Int) {
        position = i.toFloat()
        invalidate()
        mListener?.onValueChange(getFmChannel(position), getFmChannel(positionLow))
    }

    fun setLowPosition(i: Int) {
        positionLow = i.toFloat()
        invalidate()
        mListener?.onValueChange(getFmChannel(position), getFmChannel(positionLow))
    }

    fun setUnitF() {
        tempUnit = "°F"
        max = 572
        min = 32
        scaleNum = 90
        invalidate()
    }

    fun setUnitC() {
        tempUnit = "°C"
        max = 300
        min = 0
        scaleNum = 50
        invalidate()
    }

    private var mListener: OnChangerListener? = null

    interface OnChangerListener {
        fun onValueChange(highValue: Double, lowValue: Double)
    }

    fun setOnChangerListener(listener: OnChangerListener) {
        mListener = listener
    }
}